import {delay, designPage, iHTMLDivElement, iHTMLIFrameElement, onBeforeUnmount, onMounted, reactive, useRefs} from "@peryl/react-compose";
import {Alert, $notice, AiChatBox, iChatBoxHistory, Layout, LayoutSection, PageCard, PageCardContent, PageCardTitle} from "plain-design";
import {MonacoEditor} from "../components/MonacoEditor";
import './ai-3d-page.scss';
import {AI_3D_DEMO_HTML_CODE} from "./ai-3d.demo";
import {uuid} from "@peryl/utils/uuid";
import {createEffects} from "@peryl/utils/createEffects";
import {default_ai_configs} from "./AIUtils";

export default designPage(() => {

  const { refs, onRef } = useRefs({ el: iHTMLDivElement });

  const state = reactive({
    htmlCode: AI_3D_DEMO_HTML_CODE,
    userContent: `
内容是银河系，所有行星围绕太阳公转，并且行星自转，45%俯视角
行星上显示行星中文名称，标识行星是哪一颗行星，太阳也要有名称，给每颗行星设置不同的颜色做区分
    `.trim(),
    systemPrompt: `
你是一个专业的three.js前端工程师，需要你根据用户描述来生成符合用户要求的基于three.js的html代码；
如果用户要使用中文字体，中文字体包的加载地址为：https://plain-assets.oss-cn-guangzhou.aliyuncs.com/FZYaoTi_Regular.json
不要忘了写引入three.js依赖包的代码，如“<script src="https://plain-assets.oss-cn-guangzhou.aliyuncs.com/three-0.128.0/build/three.min.js"></script>”
若果代码需要使用OrbitControls，请记得引入依赖包如：“<script src="https://plain-assets.oss-cn-guangzhou.aliyuncs.com/three-0.128.0/examples/js/controls/OrbitControls.js"></script>”
这里three.js用的是0.128.0版本，如果你要用THREE.Geometry，要替换成THREE.BufferGeometry
html代码中在加载中文字体期间需要显示loading状态，字体加载完毕之后再初始化three.实例；
html中js使用ES5语法，不可以使用module语法
特别注意不需要做任何解释，只需要返回html代码；
    `
  });

  const handleMessage = async ({ message, userContent, addHistory }: { message: string, userContent: string, addHistory: (history: iChatBoxHistory) => void }): Promise<iChatBoxHistory | iChatBoxHistory[] | void> => {
    if (message.slice(0, 14) == "<!DOCTYPE html" && message.slice(-7) == "</html>") {
      state.htmlCode = message;
      reloadHtml(state.htmlCode);
      return [{ role: 'assistant', content: '已经生成完毕', id: uuid() }];
    } else if (message.slice(0, 7) !== "```html" || message.slice(-3) !== "```") {
      return [{ role: 'assistant', content: "生成失败！请换一个描述要求。", id: uuid() }];
    } else {
      state.htmlCode = message.slice(8, -3);
      reloadHtml(state.htmlCode);
      return [{ role: 'assistant', content: '已经生成完毕', id: uuid() }];
    }
  };

  const { effects: frameEffects } = createEffects();
  onBeforeUnmount(frameEffects.clear);

  const reloadHtml = async (htmlCode: string) => {
    frameEffects.clear();

    const iframe = document.createElement('iframe') as any as HTMLIFrameElement;
    iframe.style.height = '100%';
    iframe.style.width = '100%';
    refs.el!.appendChild(iframe);
    const iframeDoc = iframe.contentDocument || iframe.contentWindow!.document;
    iframeDoc.open();
    iframeDoc.write(htmlCode);
    iframeDoc.close();
    frameEffects.push(() => refs.el!.removeChild(iframe));
  };

  onMounted(() => {reloadHtml(state.htmlCode);});

  return () => (
    <PageCard full className="ai-3d-page">
      <PageCardTitle title="文生3D场景"></PageCardTitle>
      <PageCardContent full noPadding>
        <Layout fullHeight>
          <LayoutSection position="left" modelValue={500} noPadding>
            <Layout vertical fullHeight>
              <LayoutSection position="top" modelValue={500}>
                <AiChatBox
                  fitHeight
                  placeholder="请描述你要生成的3D场景内容"
                  systemContent={state.systemPrompt}
                  handleMessage={handleMessage}
                  aiConfig={default_ai_configs.doubao_dsv3}
                  v-slots={{
                    prepend: () => <>
                      <Alert icon={null} size="mini">
                        <div>1. 你可以与AI对话生成3D交互场景，基于three.js实现；右侧可以预览体验3D内容；</div>
                        <div>2. 比如输入：渲染一个正四面体，初始观察俯视角45°；每面都用不同颜色展示；要支持拖拽调整视角</div>
                        <div>3. 比如输入：渲染一个正六面体，初始观察俯视角45°；每面都用不同颜色展示；要支持拖拽调整视角</div>
                        <div>4. 远程加载模型“https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_mi_11_pro/xiaomi_mi_11_pro/scene.gltf”，要支持缩放以及拖拽移动视角，背景色为#f2f2f2</div>
                        <div>5. 远程加载模型“https://plain-assets.oss-cn-guangzhou.aliyuncs.com/skeleton_pre-cut/scene.gltf”，要支持缩放以及拖拽移动视角，背景色为#f2f2f2</div>
                      </Alert>
                    </>
                  }}
                />
              </LayoutSection>
              <LayoutSection noPadding className="html-editor-section">
                <MonacoEditor v-model={state.htmlCode} language="html" fullHeight/>
              </LayoutSection>
            </Layout>
          </LayoutSection>
          <LayoutSection noPadding fixedInner>
            <div ref={onRef.el} style={{ height: '100%' }}/>
          </LayoutSection>
        </Layout>
      </PageCardContent>
    </PageCard>
  );
});
